package ctrl;

import java.util.Vector;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Characters;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.PersistentObject;
import net.rim.device.api.system.PersistentStore;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.TouchEvent;
import net.rim.device.api.ui.component.LabelField;
import code.AppSettings;
import code.Config;

public class ListStyleButtonField extends Field
{
    public static final int DRAWPOSITION_TOP = 0;
    public static final int DRAWPOSITION_BOTTOM = 1;
    public static final int DRAWPOSITION_MIDDLE = 2;
    public static final int DRAWPOSITION_SINGLE = 3;
    
    private static final int LISTSTYLE_ALARMCLOCK=0;
    private static final int LISTSTYLE_WORLDCLOCK=1;
    private static final int LISTSTYLE_REMINDER=2;
    
    private static final int CORNER_RADIUS = 12;
    
    private static final int HPADDING = Display.getWidth() <= 320 ? 4 : 6;
    private static final int VPADDING = 4;
    
    private static final boolean USING_LARGE_ICON=Display.getWidth()<640 ? false : true;
    
    private static int COLOR_BACKGROUND = 0xFFFFFF;
    private static int COLOR_BORDER = 0xBBBBBB;
    private static int COLOR_BACKGROUND_FOCUS = 0x186DEF;
    private static final int COLOR_LIST_DISABLED = Color.DARKGRAY;//0x6D6D6D;//0x6A6A6A;

/*    
	private static final int FONT_SIZE_TITLE=0;
	private static final int FONT_SIZE_TIME=1;
	private static final int FONT_SIZE_DAYS=2;
	private static final int FONT_SIZE_DATE=3;
	private static final int FONT_SIZE_DATE_OF_BIRTH=4;
	private static final int FONT_SIZE_NEXTAGE_TIPS=5;
	private static final int FONT_SIZE_REMAINING_DAYS=6;
	
	private static final int FONT_SIZE_NORMAL=0;
	private static final int FONT_SIZE_LARGE=1;
*/
    
    //private Bitmap _leftIcon;
    private Bitmap _iconNormal=USING_LARGE_ICON ? Bitmap.getBitmapResource("listAlarmIcon_large.png") : Bitmap.getBitmapResource("listAlarmIcon.png");
    private Bitmap _iconDisabled=USING_LARGE_ICON ? Bitmap.getBitmapResource("listAlarmIcon_large_disabled.png") : Bitmap.getBitmapResource("listAlarmIcon_disabled.png");
    
    private MyLabelField _labelTitle;
    private MyLabelField _labelTime;
    private MyLabelField _labelDays;
    private MyLabelField _labelDate;
    private MyLabelField _labelNextAgeTips;
    private MyLabelField _labelRemainingDays;
    private MyLabelField _labelDateOfBirth;
    
    private boolean _enabled;
    
    //private int _targetHeight;
    private int _rightOffset;
    private int _leftOffset;
    private int _labelHeight;
    private int _listStyle;
    
    private int _drawPosition = -1;
    
	private static PersistentObject _store;
	private static Vector _data;
	private static int _fontSize=1;

	private static Font FONT_TITLE;
	private static Font FONT_TIME;
	private static Font FONT_DAYS;
	private static Font FONT_DATE;
	private static Font FONT_DATE_OF_BIRTH;
	private static Font FONT_NEXTAGE_TIPS;
	private static Font FONT_REMAINING_DAYS;
	
    /**
     * 添加 Alarm Clock 项目
     * @param title 标题
     * @param time 时间
     * @param days 工作日
     * @param enabled 启用/禁用
     * @param listStyle 暂留
     */
    public ListStyleButtonField(String title, String time, String days, boolean enabled)
    {
        super(USE_ALL_WIDTH | Field.FOCUSABLE);

		if(!_data.isEmpty())
		{
	    	for(int i=0; i<_data.size(); i++)
	    	{
	    		if(_data.elementAt(i) instanceof AppSettings)
	    		{
	    			AppSettings appSettings=(AppSettings) _data.elementAt(i);
	    			
	    			_fontSize=appSettings.getFontSize();
	    		}
	    	}
		}

        _labelTitle = new MyLabelField(title);
        _labelTime=new MyLabelField(time);
        _labelDays=new MyLabelField(days);

        _enabled=enabled;
        _listStyle=LISTSTYLE_ALARMCLOCK;

        setFontSize(_fontSize);
        
		_iconNormal=USING_LARGE_ICON ? Bitmap.getBitmapResource("listAlarmIcon_large.png") : Bitmap.getBitmapResource("listAlarmIcon.png");
		_iconDisabled=USING_LARGE_ICON ? Bitmap.getBitmapResource("listAlarmIcon_large_disabled.png") : Bitmap.getBitmapResource("listAlarmIcon_disabled.png");        		
    }

    /**
     * 添加 World Clock 项目
     * @param title 标题
     * @param time 时间
     * @param date 日期
     * @param listStyle 暂留
     */
    public ListStyleButtonField(String title, String time, String date)
    {
        super(USE_ALL_WIDTH | Field.FOCUSABLE);

		if(!_data.isEmpty())
		{
	    	for(int i=0; i<_data.size(); i++)
	    	{
	    		if(_data.elementAt(i) instanceof AppSettings)
	    		{
	    			AppSettings appSettings=(AppSettings) _data.elementAt(i);
	    			
	    			_fontSize=appSettings.getFontSize();
	    		}
	    	}
		}

        _labelTitle = new MyLabelField(title);
        _labelTime=new MyLabelField(time);
        _labelDate=new MyLabelField(date);
       
        _enabled=true;
        _listStyle=LISTSTYLE_WORLDCLOCK;

        setFontSize(_fontSize);
        
		_iconNormal=USING_LARGE_ICON ? Bitmap.getBitmapResource("listWorldIcon_large.png") : Bitmap.getBitmapResource("listWorldIcon.png");
    }

    /**
     * 添加 Birthday Reminder 项目
     * @param title 标题
     * @param dateOfBirth 生日日期
     * @param nextAge 即将到达的年龄
     * @param remainingDays 距生日剩余天数
     */
    public ListStyleButtonField(String title, String dateOfBirth, String nextAge, String remainingDays)
    {
        super(USE_ALL_WIDTH | Field.FOCUSABLE);
               
		if(!_data.isEmpty())
		{
	    	for(int i=0; i<_data.size(); i++)
	    	{
	    		if(_data.elementAt(i) instanceof AppSettings)
	    		{
	    			AppSettings appSettings=(AppSettings) _data.elementAt(i);
	    			
	    			_fontSize=appSettings.getFontSize();
	    		}
	    	}
		}
        
        _labelTitle = new MyLabelField(title);
        _labelDateOfBirth=new MyLabelField(dateOfBirth);
        _labelNextAgeTips=new MyLabelField(nextAge);
        _labelRemainingDays=new MyLabelField(remainingDays);
       
        _enabled=true;
        _listStyle=LISTSTYLE_REMINDER;

        setFontSize(_fontSize);
        
		_iconNormal=USING_LARGE_ICON ? Bitmap.getBitmapResource("listReminderIcon_large.png") : Bitmap.getBitmapResource("listReminderIcon.png");
    }

    public void setDrawPosition(int drawPosition)
    {
        _drawPosition = drawPosition;
    }
    
    public void layout(int width, int height)
    {
        _leftOffset = _iconNormal.getWidth() + HPADDING*2;
        _rightOffset = HPADDING;
        
        _labelTitle.layout(width - _leftOffset - _rightOffset, height);
        _labelHeight = _labelTitle.getHeight();
        
        if(_labelTime!=null) {_labelTime.layout(width- _leftOffset - _rightOffset, height);}
        
        if(_labelNextAgeTips!=null) {_labelNextAgeTips.layout(width-_leftOffset-_rightOffset, height);}
        
        if(_labelRemainingDays!=null && _labelNextAgeTips!=null)
        {
        	_labelRemainingDays.layout(width-_leftOffset-_rightOffset, height);
        }
        
    	if(_labelDays!=null)
    	{
    		_labelDays.layout(width - _leftOffset - _rightOffset - _labelTime.getWidth(), height);
    		_labelHeight+=_labelDays.getHeight();
    	}

    	if(_labelDate!=null)
    	{
    		_labelDate.layout(width - _leftOffset - _rightOffset - _labelTime.getWidth(), height);
    		_labelHeight+=_labelDate.getHeight();
    	}

    	if(_labelDateOfBirth!=null)
    	{
    		_labelDateOfBirth.layout(width - _leftOffset - _rightOffset - _labelRemainingDays.getWidth(), height);
    		_labelHeight+=_labelDateOfBirth.getHeight();
    	}

        //int extraVPaddingNeeded = 0;
        //if(_labelHeight < _targetHeight) {extraVPaddingNeeded =  (_targetHeight - _labelHeight) / 2;}
        
        setExtent(width, _labelHeight+10);//+2* extraVPaddingNeeded);
    }

    public void setTitleText(String text)
    {
    	_labelTitle.setText(text);
        updateLayout();
        
        Manager m=this.getManager();
        if(m!=null) {m.invalidate();}
    }
    
    public String getTitleText()
    {
    	return _labelTitle.getText();
    }
    
    public void setTimeText(String text)
    {
    	_labelTime.setText(text);
    	updateLayout();

    	Manager m=super.getManager();
        if(m!=null) {m.invalidate();}
    }

    public void setDaysText(String text)
    {
    	_labelDays.setText(text);
    	updateLayout();
    	
        Manager m=this.getManager();
        if(m!=null) {m.invalidate();}
	}

    public void setDateText(String text)
    {
    	_labelDate.setText(text);
    	updateLayout();
    	
        Manager m=this.getManager();
        if(m!=null) {m.invalidate();}
	}
    
    public void setFontSize(int size)
    {
    	switch (_listStyle)
    	{
			case LISTSTYLE_ALARMCLOCK:
		    	switch (size)
		    	{
		    		case 0:
		    			FONT_TITLE=Config.FONT_TITLE_SMALL;
		    			FONT_TIME=Config.FONT_TIME_SMALL;
		    			FONT_DAYS=Config.FONT_DAYS_SMALL;

		    			break;
		    		case 1:
		    			FONT_TITLE=Config.FONT_TITLE_NORMAL;
		    			FONT_TIME=Config.FONT_TIME_NORMAL;
		    			FONT_DAYS=Config.FONT_DAYS_NORMAL;

		    			break;
		    		case 2:
		    			FONT_TITLE=Config.FONT_TITLE_LARGE;
		    			FONT_TIME=Config.FONT_TIME_LARGE;
		    			FONT_DAYS=Config.FONT_DAYS_LARGE;

		    			break;
		    	}
		    	
				break;
			case LISTSTYLE_WORLDCLOCK:
				switch (size)
				{
					case 0:
						FONT_TITLE=Config.FONT_TITLE_SMALL;
						FONT_TIME=Config.FONT_TIME_SMALL;
						FONT_DATE=Config.FONT_DATE_SMALL;

						break;
					case 1:
						FONT_TITLE=Config.FONT_TITLE_NORMAL;
						FONT_TIME=Config.FONT_TIME_NORMAL;
						FONT_DATE=Config.FONT_DATE_NORMAL;
						
						break;
					case 2:
						FONT_TITLE=Config.FONT_TITLE_LARGE;
						FONT_TIME=Config.FONT_TIME_LARGE;
						FONT_DATE=Config.FONT_DATE_LARGE;
						
						break;
				}

				break;
			case LISTSTYLE_REMINDER:
				switch (size)
				{
					case 0:
						FONT_TITLE=Config.FONT_TITLE_SMALL;
						FONT_DATE_OF_BIRTH=Config.FONT_DATEOFBIRTH_SMALL;
						FONT_NEXTAGE_TIPS=Config.FONT_NEXTAGETIPS_SMALL;
						FONT_REMAINING_DAYS=Config.FONT_REMAININGDAYS_SMALL;

						break;
					case 1:
						FONT_TITLE=Config.FONT_TITLE_NORMAL;
						FONT_DATE_OF_BIRTH=Config.FONT_DATEOFBIRTH_NORMAL;
						FONT_NEXTAGE_TIPS=Config.FONT_NEXTAGETIPS_NORMAL;
						FONT_REMAINING_DAYS=Config.FONT_REMAININGDAYS_NORMAL;
						
						break;
					case 2:
						FONT_TITLE=Config.FONT_TITLE_LARGE;
						FONT_DATE_OF_BIRTH=Config.FONT_DATEOFBIRTH_LARGE;
						FONT_NEXTAGE_TIPS=Config.FONT_NEXTAGETIPS_LARGE;
						FONT_REMAINING_DAYS=Config.FONT_REMAININGDAYS_LARGE;
						
						break;
					}

				break;
		}

    	if(_labelTitle!=null) {_labelTitle.setFont(FONT_TITLE);}
    	if(_labelTime!=null) {_labelTime.setFont(FONT_TIME);}
    	if(_labelDays!=null) {_labelDays.setFont(FONT_DAYS);}
    	if(_labelDate!=null) {_labelDate.setFont(FONT_DATE);}
    	if(_labelDateOfBirth!=null) {_labelDateOfBirth.setFont(FONT_DATE_OF_BIRTH);}
    	if(_labelNextAgeTips!=null) {_labelNextAgeTips.setFont(FONT_NEXTAGE_TIPS);}
    	if(_labelRemainingDays!=null) {_labelRemainingDays.setFont(FONT_REMAINING_DAYS);}
    	
    	updateLayout();
    }
    
    public void setDateOfBirthText(String text)
    {
    	_labelDateOfBirth.setText(text);
    	updateLayout();
    	
        Manager m=this.getManager();
        if(m!=null) {m.invalidate();}
	}
    
    public void setNextAgeTipsText(String text)
    {
    	_labelNextAgeTips.setText(text);
    	updateLayout();
    	
        Manager m=this.getManager();
        if(m!=null) {m.invalidate();}
	}

    public void setRemainingDaysText(String text)
    {
    	_labelRemainingDays.setText(text);
    	updateLayout();
    	
        Manager m=this.getManager();
        if(m!=null) {m.invalidate();}
	}
    
    static
	{
    	_store=PersistentStore.getPersistentObject(0xaa041103a4a17b66L); //blackberry_alarmclock_worldclock_settings_id
		
		synchronized(_store)
		{
			if(_store.getContents()==null)
			{
				_store.setContents(new Vector());
				_store.forceCommit();
			}
		}
		
		try {
			_data=new Vector();
			_data=(Vector) _store.getContents();
		} catch (final Exception e) {}
	}

    protected void paint(Graphics g)
    {
        // Logo Bitmap
    	if(_enabled)
    	{
    		g.drawBitmap(HPADDING, (getHeight()-_iconNormal.getHeight())/2, _iconNormal.getWidth(), _iconNormal.getHeight(), _iconNormal, 0, 0);
    	} else {
    		g.drawBitmap(HPADDING, (getHeight()-_iconDisabled.getHeight())/2, _iconDisabled.getWidth(), _iconDisabled.getHeight(), _iconDisabled, 0, 0);
    	}
        
    	if(!_enabled) {g.setColor(COLOR_LIST_DISABLED);}
    	
        // Title Text
        try
        {
        	g.setFont(FONT_TITLE);
        	g.pushRegion(_leftOffset, VPADDING, _labelTitle.getWidth(), _labelTitle.getHeight(), 0, 0);
            _labelTitle.paint(g);
        } finally {
        	g.popContext();
        }
        
        // Time Text
        if(_labelTime!=null)
        {
            try
        	{
            	g.setFont(FONT_TIME);
        		g.pushRegion(getWidth() - HPADDING - _labelTime.getWidth(), (getHeight() - _labelTime.getHeight())/2, _labelTime.getWidth(), _labelTime.getHeight(),0,0);
        		_labelTime.paint(g);
        	} finally{
        		g.popContext();
        	}       	
        }
        
        // Next Age Tips Text
        if(_labelNextAgeTips!=null)
        {
            try
        	{
            	g.setFont(FONT_NEXTAGE_TIPS);
        		g.pushRegion(getWidth() - HPADDING - _labelNextAgeTips.getWidth(), (getHeight()-_labelNextAgeTips.getHeight()-_labelRemainingDays.getHeight())/2+VPADDING, _labelNextAgeTips.getWidth(), _labelNextAgeTips.getHeight(),0,0);
        		_labelNextAgeTips.paint(g);
        	} finally{
        		g.popContext();
        	}       	
        }
        
        //Remaining Days Text
        if(_labelRemainingDays!=null)
        {
            try
        	{
            	g.setFont(FONT_REMAINING_DAYS);
        		g.pushRegion(getWidth()-HPADDING-_labelNextAgeTips.getWidth()+(_labelNextAgeTips.getWidth()-_labelRemainingDays.getWidth())/2, _labelNextAgeTips.getHeight()+VPADDING/2, _labelRemainingDays.getWidth(), _labelRemainingDays.getHeight(),0,0);
        		_labelRemainingDays.paint(g);
        	} finally{
        		g.popContext();
        	}       	
        }
                
        // Days & Date Text
        if(_labelDays!=null || _labelDate!=null || _labelDateOfBirth!=null)
        {
        	try
        	{
        		if(g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS))
        		{
        			if(!_enabled)
        			{
        				g.setColor(COLOR_LIST_DISABLED);
        			} else {
        				g.setColor(Color.WHITE);
        			}
        		} else {
        			if(!_enabled)
        			{
        				g.setColor(COLOR_LIST_DISABLED);
        			} else {
        				g.setColor(Color.GRAY);	
        			}
    			}

        		if(_labelDays!=null)
        		{
            		g.setFont(FONT_DAYS);
            		g.pushRegion(_leftOffset, getHeight()-_labelDays.getHeight()-VPADDING, _labelDays.getWidth(), _labelDays.getHeight(),0,0);
            		_labelDays.paint(g);
        		}
        		
        		if(_labelDate!=null)
        		{
            		g.setFont(FONT_DATE);
            		g.pushRegion(_leftOffset, getHeight()-_labelDate.getHeight()-VPADDING, _labelDate.getWidth(), _labelDate.getHeight(),0,0);
            		_labelDate.paint(g);
        		}
        		
        		if(_labelDateOfBirth!=null)
        		{
            		g.setFont(FONT_DATE_OF_BIRTH);
            		g.pushRegion(_leftOffset, getHeight()-_labelDateOfBirth.getHeight()-VPADDING, _labelDateOfBirth.getWidth(), _labelDateOfBirth.getHeight(),0,0);
            		_labelDateOfBirth.paint(g);
        		}
        	} finally{
        		g.popContext();
        	}	
        }
    }
    
    protected void paintBackground(Graphics g)
    {
        if(_drawPosition < 0)
        {
            super.paintBackground(g);
            return;
        }
        
        int oldColour = g.getColor();
        
        switch(_listStyle)
        {
			case LISTSTYLE_ALARMCLOCK:
        		COLOR_BACKGROUND_FOCUS = 0x186DEF;
        		
        		break;
			case LISTSTYLE_WORLDCLOCK:
        		COLOR_BACKGROUND_FOCUS = 0x0A9000;
        		
        		break;
			case LISTSTYLE_REMINDER:
        		COLOR_BACKGROUND_FOCUS = 0xC72F00;

        		break;
		}
        
        int background = g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS) ? COLOR_BACKGROUND_FOCUS : COLOR_BACKGROUND;
        
        try {
            if(_drawPosition == 0)
            {
                // Top
                g.setColor(background);
                g.fillRoundRect(0, 0, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.setColor(COLOR_BORDER);
                g.drawRoundRect(0, 0, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
            } else if(_drawPosition == 1)
            {
                // Bottom 
                g.setColor(background);
                g.fillRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.setColor(COLOR_BORDER);
                g.drawRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
            } else if(_drawPosition == 2)
            {
                // Middle
                g.setColor(background);
                g.fillRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + 2 * CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.setColor(COLOR_BORDER);
                g.drawRoundRect(0, -CORNER_RADIUS, getWidth(), getHeight() + 2 * CORNER_RADIUS, CORNER_RADIUS, CORNER_RADIUS);
                g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
            } else {
                // Single
                g.setColor(background);
                g.fillRoundRect(0, 0, getWidth(), getHeight(), CORNER_RADIUS, CORNER_RADIUS);
                g.setColor(COLOR_BORDER);
                g.drawRoundRect(0, 0, getWidth(), getHeight(), CORNER_RADIUS, CORNER_RADIUS);
            }
        } finally {
            g.setColor(oldColour);
        }
    }
    
    protected void drawFocus(Graphics g, boolean on)
    {
        if(_drawPosition < 0)
        {
            //super.drawFocus(g, on);
        } else {
            boolean oldDrawStyleFocus = g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS);
            try {
                if(on)
                {
                	g.setColor(Color.WHITE);
                    g.setDrawingStyle(Graphics.DRAWSTYLE_FOCUS, true);
                }
                paintBackground(g);
                paint(g);
            } finally {
                g.setDrawingStyle(Graphics.DRAWSTYLE_FOCUS, oldDrawStyleFocus);
            }
        }
    }
    
    protected boolean keyChar(char key, int status, int time) 
    {
        if(key==Characters.ENTER)
        {
            clickButton();
            return true;
        } else if(key==Characters.SPACE && _listStyle==0)
        {
        	_enabled=!_enabled;
        	super.invalidate();
        }
        
        return super.keyChar(key, status, time);
    }
    
    protected boolean navigationClick(int status, int time) 
    {
        clickButton(); 
        return true;    
    }
    
    protected boolean trackwheelClick(int status, int time)
    {        
        clickButton();    
        return true;
    }
    
    protected boolean invokeAction(int action) 
    {
        switch(action)
        {
            case ACTION_INVOKE:
                clickButton(); 
                return true;
        }
        return super.invokeAction(action);
    }
    
    /**
     * A public way to click this button
     */
    public void clickButton() 
    {
        fieldChangeNotify(0);
    }
       
    protected boolean touchEvent(TouchEvent message)
    {
        int x = message.getX(1);
        int y = message.getY(1);
        
        if(x < 0 || y < 0 || x > getExtent().width || y > getExtent().height)
        {
            return false;
        }
        
        switch(message.getEvent())
        {
            case TouchEvent.UNCLICK:
                clickButton();
                return true;
        }
        
        return super.touchEvent(message);
    }
    
    public void setDirty(boolean dirty) {}
    public void setMuddy(boolean muddy) {}
}

class MyLabelField extends LabelField
{
    public MyLabelField(String text)
    {
        super(text, LabelField.ELLIPSIS);
    }
    
	public void layout(int width, int height)
	{   
		super.layout(width, height);
	}   

	public void paint(Graphics g) 
	{
		super.paint(g);
	}
}